package praktikumid.w11.p1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class StringsUndo {
	static class Element {
		boolean isVisible = true;
		String name;
		
		public Element(Element e) { // copy
			name = e.name;
		}
		
		public Element(String name) {
			this.name = name;
		}
		@Override
		public String toString() {
			return name;
		}
	}
	
	static class Action {
		// UndoManager
		static final int TYPE_ADD = 1;
		static final int TYPE_MODIFY = 2;
		static final int TYPE_REMOVE = 3;
		int type = TYPE_ADD;
		
		Element elStart; // add, remove -> elements[i]
		Element elInitial; // modify
		
		public Action(Element e) {
			elStart = e;
		}
	
		public Action(Element e, int type) {
			elStart = e;
			this.type = type;
		}
		
		public Action(Element eStart, Element eEnd) {
			type = TYPE_MODIFY;
			elStart = eStart;
			elInitial = eEnd;
		}
		
		public void undo() {
			switch (type) {
			case TYPE_ADD:
				elStart.isVisible = false;
				break;
			case TYPE_REMOVE:
				elStart.isVisible = true;
				break;
			case TYPE_MODIFY:
				System.out.println(elStart);
				System.out.println(elInitial);
				elStart.name = elInitial.name;
				break;
			}
		}
		
	}
	
	static List<Element> elements = new ArrayList<Element>();
	
	static List<Action> actions = new ArrayList<Action>();
	static int actionIndex = 0;
	
	public static void main(String[] args) throws IOException {

		BufferedReader br = new BufferedReader(
				new InputStreamReader(System.in));
		while(true) {
			/*
			 * 1 tere
			 * tokens[0] = "1"
			 * tokens[1] = "tere"
			 * 
			 * op = 1
			 * new Element("tere");
			 * 
			 */
			debugHistory();
			printHelp();
			String line = br.readLine();
			String[] tokens = line.split(" ");
			int op = Integer.valueOf(tokens[0]);
			int elid = -1;
			switch (op) {
			case 1:
				
				Element el = new Element(tokens[1]);
				elements.add(el);
				actions.add(actionIndex, new Action(el));
				break;
			case 2: // rename
				// tokens[1] -> index
				elid = Integer.valueOf(tokens[1]);
				Element e = elements.get(elid);
				Element e2 = new Element(e);
				e.name = tokens[2];
				actions.add(actionIndex, new Action(e, e2));
				break;
			case 3: // delete
				elid = Integer.valueOf(tokens[1]);
				//elements.remove(elid);
				Element e3 = elements.get(elid);
				e3.isVisible = false;
				actions.add(actionIndex, new Action(e3, Action.TYPE_REMOVE));
				break;
			case 4:
				printElements();
				break;
			case 5:
				if (actions.size() > 0) {
					actionIndex--;
					Action a = actions.get(actionIndex);
					a.undo();
				}
				break;
			case 0:
				System.exit(0);
				
			}
			if (op > 0 && op < 4) {
				actionIndex++;
			}
			
		}
	}
	public static void printElements() {
		for (int i = 0; i < elements.size(); i++) {
			if (elements.get(i).isVisible) {
				System.out.println(i + ". " + elements.get(i));
			}
		}
	}
	
	public static void debugHistory() {
		System.out.println("history index: " + actionIndex);
	}
	
	public static void printHelp() {
		System.out.println("  1 add element [1 name]");
		System.out.println("  2 change element [2 elid name]");
		System.out.println("  3 delete element [3 elid]");
		System.out.println("  4 list elements [4]");
		System.out.println("  5 undo [5]");
		System.out.println("  0 exit [0]");
	}
}